package com.chy.blog_web.core.el;

import java.util.Iterator;
import java.util.Map;

import javax.el.ExpressionFactory;
import javax.el.ValueExpression;

import com.chy.blog_web.core.util.StringUtil;
import de.odysseus.el.util.SimpleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 描述：EL表达式解析
 * 作者：chenhuiyan
 * 时间：2024/08/13
 */
public class ELSession {

    private static Logger logger = LoggerFactory.getLogger(ELSession.class);

    public final static String BEAN = "bean";

    public final static String PREFIX = "epx";

    private static ExpressionFactory factory = ExpressionFactory.newInstance();


    /**
     * 获取SimpleContext
     * @return
     */
    public static SimpleContext getSimpleContext() {
        SimpleContext simpleContext = new SimpleContext();
        /*try {
            //----------解析函数
            Map<String, Entity> map = ELFunction.getFunctionMap(systemId);
            if (null != map) {
                for (Map.Entry<String, Entity> entry : map.entrySet()) {
                    Entity functionEntity = entry.getValue();
                    String prefix = functionEntity.getStringValue(FmFunction.PREFIX); //前缀
                    String methodName = functionEntity.getStringValue(FmFunction.METHOD); //函数方法
                    String mainClass = functionEntity.getStringValue(FmFunction.CLASS); //函数类
                    String paramTypes = functionEntity.getStringValue(FmFunction.PARAM_TYPE); //参数：string,string,string
                    if (StringUtils.isBlank(mainClass)) {
                        continue;
                    }
                    Class<?> mc = Class.forName(mainClass);
                    if (null != mc) {
                        Class<?>[] c = ELFunction.getParameterTypeClass(paramTypes);
                        try {
                            if (null != c) {
                                simpleContext.setFunction(prefix, methodName, mc.getMethod(methodName, c));
                            } else {
                                simpleContext.setFunction(prefix, methodName, mc.getMethod(methodName));
                            }
                        } catch (Exception e) {
                            logger.error(e.getMessage());
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        return simpleContext;
    }

    /**
     * 解析表达式，结果以字符串返回
     *
     * @param prefix     对象前缀
     * @param data       传入对象
     * @param expression
     * @return
     */
    public static String parse(String prefix, Object data, String expression) {
        try {
            SimpleContext context = getSimpleContext();
            context.setVariable(prefix, factory.createValueExpression(data, Map.class));
            ValueExpression expr = factory.createValueExpression(context, expression, Object.class);
            Object obj = expr.getValue(context);
            if (obj != null)
                return obj.toString();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return expression;
    }


    public static String parse(Object data, String expression) {
        return parse("bean", data, expression);
    }

    /**
     * 解析表达式并获取BOOLEAN值
     *
     * @param expression 表达式
     * @param data       参数
     * @return
     */
    public static boolean getBooleanValue(String expression, Map data) throws Exception {
        try {
            SimpleContext context = getSimpleContext();
            if (data != null && data.size() > 0) {
                Iterator it = data.keySet().iterator();
                while (it.hasNext()) {
                    String key = (String) it.next();
                    context.setVariable(key, factory.createValueExpression(data.get(key), data.get(key).getClass()));
                }
            }
            ValueExpression expr = factory.createValueExpression(context, expression, boolean.class);
            return (Boolean) expr.getValue(context);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    public static boolean getBooleanResult(String expression, Map data) throws Exception {
        try {
            SimpleContext context = getSimpleContext();
            if (data != null && data.size() > 0) {
                Iterator it = data.keySet().iterator();
                while (it.hasNext()) {
                    String key = (String) it.next();
                    context.setVariable(key, factory.createValueExpression(data.get(key), data.get(key).getClass()));
                }
            }
            ValueExpression expr = factory.createValueExpression(context, expression, boolean.class);
            return (Boolean) expr.getValue(context);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 表达式解析
     *
     * @param params     传入参数
     * @param expression 表达式
     * @return
     */
    public static String getString(Map params, String expression) {
        try {
            if (StringUtil.notNull(expression) && expression.indexOf("#{") >= 0) {
                SimpleContext context = getSimpleContext();
                Iterator it = params.keySet().iterator();
                while (it.hasNext()) {
                    String key = (String) it.next();
                    Object obj = params.get(key);
                    context.setVariable(key, factory.createValueExpression(obj, obj.getClass()));
                }
                ValueExpression expr = factory.createValueExpression(context, expression.trim(), Object.class);
                Object result = expr.getValue(context);
                if (result != null)
                    return result.toString();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return expression;
    }

    public static boolean getBoolean(Map params, String expression, boolean flag) {
        try {
            if (StringUtil.notNull(expression) && expression.indexOf("#{") >= 0) {
                SimpleContext context = getSimpleContext();
                Iterator it = params.keySet().iterator();
                while (it.hasNext()) {
                    String key = (String) it.next();
                    Object obj = params.get(key);
                    context.setVariable(key, factory.createValueExpression(obj, obj.getClass()));
                }
                ValueExpression expr = factory.createValueExpression(context, expression.trim(), Object.class);
                Object result = expr.getValue(context);
                if (result != null)
                    return (Boolean) expr.getValue(context);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return flag;
    }

    /**
     * 得到字符串值
     *
     * @param data
     * @param expression
     * @return
     */
    public static String getStringValue(Map<String, String> data, String expression) {
        try {
            if (null != data) {
                SimpleContext context = getSimpleContext();
                for (String key : data.keySet()) {
                    String value = data.get(key);
                    context.setVariable(key, factory.createValueExpression(value, String.class));
                }
                ValueExpression expr = factory.createValueExpression(context, expression.trim(), Object.class);
                Object result = expr.getValue(context);
                if (result != null)
                    return result.toString();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "";
    }

    public static String getStringOrNull(Map params, String expression) {
        try {
            if (StringUtil.notNull(expression) && expression.indexOf("#{") >= 0) {
                SimpleContext context = getSimpleContext();
                Iterator it = params.keySet().iterator();
                boolean flag = false;
                while (it.hasNext()) {
                    String key = (String) it.next();
                    Object obj = params.get(key);
                    if (key.indexOf('|') > -1) {
                        key = key.replace('|', '_');
                    }
                    context.setVariable(key, factory.createValueExpression(obj, obj.getClass()));
                    if (expression.indexOf(key.trim()) == 2 && key.trim().length() == expression.trim().length() - 3) {
                        flag = true;
                        break;
                    }
                }

                if (flag) {
                    ValueExpression expr = factory.createValueExpression(context, expression.trim(), Object.class);
                    Object result = expr.getValue(context);
                    if (result != null)
                        return result.toString();
                } else {
                    ValueExpression expr = factory.createValueExpression(context, expression.trim(), Object.class);
                    Object result = expr.getValue(context);
                    if (result != null) {
                        return result.toString();
                    } else {
                        return " ";
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return " ";
        }
        return expression;
    }

    public static Object getObjectResult(Map params, String expression) {
        Object result = null;
        try {
            if (StringUtil.notNull(expression) && expression.indexOf("#{") >= 0) {
                SimpleContext context = getSimpleContext();
                Iterator it = params.keySet().iterator();
                while (it.hasNext()) {
                    String key = (String) it.next();
                    Object obj = params.get(key);
                    context.setVariable(key, factory.createValueExpression(obj, obj.getClass()));
                }
                ValueExpression expr = factory.createValueExpression(context, expression.trim(), Object.class);
                result = expr.getValue(context);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }


    /**
     * boolean验证（操作权限检查）
     *
     * @param params
     * @param expression
     * @param flag
     * @return
     */
    public static boolean getBooleanByUser(Map<String, Object> params, String expression, boolean flag) {
        try {
            if (StringUtil.notNull(expression) && expression.indexOf("#{") >= 0) {
                SimpleContext context = getSimpleContext();
                Iterator<String> it = params.keySet().iterator();
                String key = "";
                Object obj = null;
                while (it.hasNext()) {
                    key = it.next();
                    obj = params.get(key);
                    context.setVariable(key, factory.createValueExpression(obj, obj.getClass()));
                }
                ValueExpression expr = factory.createValueExpression(context, expression.trim(), Object.class);
                Object result = expr.getValue(context);
                if (null != result)
                    flag = (Boolean) expr.getValue(context);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return flag;
    }
}
